<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { Modal } from 'ant-design-vue';
import { type Connection, ConnectionMode, type Edge, type Node, VueFlow, useVueFlow } from '@vue-flow/core';
import { Background } from '@vue-flow/background';
import { MiniMap } from '@vue-flow/minimap';
import { Controls } from '@vue-flow/controls';
import '@vue-flow/core/dist/style.css';
import '@vue-flow/core/dist/theme-default.css';
import '@vue-flow/controls/dist/style.css';
import '@vue-flow/minimap/dist/style.css';

import {
  fetchBatchCreateTenantNodeMappings,
  fetchCreateTenantNodeMapping,
  fetchDeleteTenantNodeMapping,
  fetchGetAllTenantNodeMappings
} from '@/service/api/tenant-node-mapping';
import { fetchGetAllTenants } from '@/service/api/tenant';
import { fetchOnlineNodes } from '@/service/api/node';
import { useRouterPush } from '@/hooks/common/router';
import NodeNode from './NodeNode.vue';
import TenantNode from './TenantNode.vue';
const { routerPushByKey } = useRouterPush();
// 响应式数据
const tenantList = ref<Api.SystemManage.Tenant[]>([]);
const nodeList = ref<any[]>([]);
const mappingList = ref<Api.SystemManage.TenantNodeMapping[]>([]);
const saving = ref(false);
const showMappingModal = ref(false);
const selectedMapping = ref<any>(null);
const vueFlowRef = ref();

// 节点详情弹窗相关
// const nodeDetailVisible = ref(false);
// const nodeDetailData = ref<any>(null);

// 添加映射相关
const showAddMappingModal = ref(false);
const addingMapping = ref(false);
const newMapping = ref({
  tenantId: null as number | null,
  nodeKey: null as string | null,
  status: '1' as Api.Common.EnableStatus
});

// 保存节点位置信息
const nodePositions = ref<Record<string, { x: number; y: number }>>({});

// 从localStorage加载保存的位置信息
const savedPositions = localStorage.getItem('tenant-node-mapping-positions');
if (savedPositions) {
  nodePositions.value = JSON.parse(savedPositions);
}

// Vue Flow 相关
const { getEdges, addEdges, removeEdges } = useVueFlow();

// 节点类型定义
const nodeTypes = {
  tenant: TenantNode as any,
  node: NodeNode as any
};

// 边类型定义
const edgeTypes = {};

// 元素数据
const elements = ref<(Node | Edge)[]>([]);

// 计算属性
const edges = computed(() => getEdges.value);
const hasChanges = computed(() => {
  // 这里可以添加变更检测逻辑
  return true;
});

// 租户选项 - 只显示启用状态的租户
const tenantOptions = computed(() =>
  tenantList.value
    .filter(tenant => tenant.status === '1') // 只显示启用状态的租户
    .map(tenant => ({
      label: tenant.tenantName,
      value: tenant.id
    }))
);

// 节点选项
const nodeOptions = computed(() =>
  nodeList.value.map(node => ({
    label: `${node.ip}:${node.port}`,
    value: `${node.ip}-${node.port}`
  }))
);

// 初始化数据
async function initData() {
  // 并行获取数据
  const [tenantsRes, nodesRes, mappingsRes] = await Promise.all([
    fetchGetAllTenants(),
    fetchOnlineNodes(),
    fetchGetAllTenantNodeMappings()
  ]);

  // 检查是否有错误
  if (tenantsRes.error || nodesRes.error || mappingsRes.error) {
    return;
  }

  tenantList.value = tenantsRes.data || [];
  nodeList.value = nodesRes.data || [];
  mappingList.value = mappingsRes.data || [];

  // 构建 Vue Flow 元素
  buildFlowElements();
  window.$message?.success('数据刷新成功');
}

// 构建流程图元素
function buildFlowElements() {
  const nodes: Node[] = [];
  const flowEdges: Edge[] = [];

  // 添加租户节点
  tenantList.value.forEach((tenant, index) => {
    const nodeId = `tenant-${tenant.id}`;
    const savedPosition = nodePositions.value[nodeId];

    nodes.push({
      id: nodeId,
      type: 'tenant',
      position: savedPosition || { x: 100, y: 100 + index * 120 },
      data: tenant,
      draggable: true
    });
  });

  // 添加节点节点
  nodeList.value.forEach((node, index) => {
    const nodeId = `node-${node.ip}-${node.port}`;
    const savedPosition = nodePositions.value[nodeId];

    nodes.push({
      id: nodeId,
      type: 'node',
      position: savedPosition || { x: 600, y: 100 + index * 120 },
      data: node,
      draggable: true
    });
  });

  // 添加映射关系边
  mappingList.value.forEach((mapping, _index) => {
    const tenant = tenantList.value.find(t => t.id === mapping.tenantId);
    const node = nodeList.value.find(n => n.ip === mapping.nodeIp && n.port === mapping.nodePort);

    if (tenant && node) {
      flowEdges.push({
        id: `edge-${mapping.id}`,
        source: `tenant-${tenant.id}`,
        target: `node-${node.ip}-${node.port}`,
        type: 'smoothstep',
        animated: true,
        style: { stroke: '#1890ff', strokeWidth: 2 },
        data: {
          mapping,
          tenant,
          node
        }
      });
    }
  });

  // 使用 setElements 来完全替换元素，而不是逐个添加/删除
  elements.value = [...nodes, ...flowEdges];
}

// 节点拖拽结束事件
function onNodeDragStop(event: any, node?: Node) {
  // Vue Flow可能将node数据放在event.node中
  let targetNode = node;

  if (!targetNode && event && event.node) {
    targetNode = event.node;
  }

  // 检查node参数是否存在
  if (!targetNode || !targetNode.id) {
    console.error('节点拖拽事件中node参数无效:', { event, node, targetNode });
    return;
  }

  // 保存节点位置
  nodePositions.value[targetNode.id] = targetNode.position;

  // 保存到localStorage
  localStorage.setItem('tenant-node-mapping-positions', JSON.stringify(nodePositions.value));

  // console.log('节点位置已保存:', targetNode.id, targetNode.position);
}

// 连接事件处理
function onConnect(connection: Connection) {
  const { source, target } = connection;

  // 检查是否已存在相同的连接
  const existingEdge = edges.value.find(edge => edge.source === source && edge.target === target);

  if (existingEdge) {
    window.$message?.warning('该映射关系已存在');
    return;
  }

  // 检查租户状态
  const tenant = tenantList.value.find(t => `tenant-${t.id}` === source);
  if (!tenant) {
    window.$message?.error('租户信息不存在');
    return;
  }

  if (tenant.status !== '1') {
    window.$message?.warning('禁用状态的租户不能添加映射关系');
    return;
  }

  // 创建新的边
  const newEdge: Edge = {
    id: `edge-${Date.now()}`,
    source,
    target,
    type: 'smoothstep',
    animated: true,
    style: { stroke: '#1890ff', strokeWidth: 2 },
    data: {
      isNew: true,
      tenant,
      node: nodeList.value.find(n => `node-${n.ip}-${n.port}` === target)
    }
  };

  addEdges([newEdge]);
}

// 边点击事件
function onEdgeClick(event: any) {
  const edge = event as Edge;
  console.log('边点击事件触发 - 完整参数:', { event, edge });

  // 简化处理：直接使用第一个有id和data的参数作为edge
  let targetEdge = null;

  if (edge && edge.id && edge.data) {
    targetEdge = edge;
    console.log('使用第二个参数作为edge');
  } else if (event && event.id && event.data) {
    targetEdge = event;
    console.log('使用第一个参数作为edge');
  }

  // 如果仍然没有找到，尝试从Vue Flow实例获取
  if (!targetEdge) {
    console.log('尝试从Vue Flow实例获取边信息');
    const currentEdges = getEdges.value;
    console.log('当前所有边:', currentEdges);

    // 如果有边，使用第一个（临时方案）
    if (currentEdges.length > 0) {
      targetEdge = currentEdges[0];
      console.log('使用第一个边:', targetEdge);
    } else {
      console.error('没有找到任何边');
      return;
    }
  }

  // 检查edge.data是否存在
  if (!targetEdge.data) {
    console.error('Edge.data为空:', targetEdge);
    return;
  }

  // 检查edge.id是否存在
  if (!targetEdge.id) {
    console.error('Edge.id为空:', targetEdge);
    return;
  }

  console.log('成功获取edge数据:', targetEdge.data);
  selectedMapping.value = targetEdge.data;
  showMappingModal.value = true;
}

// 节点点击事件
function onNodeClick(event: any) {
  const node = event as Node;
  console.log('点击节点:', node);
}

// 显示节点详情
function showNodeDetail(data: any) {
  console.log('双击节点，显示详情:', data);
  routerPushByKey('tenant_node-detail', { query: { ip: data.ip, port: data.port } });
  // nodeDetailData.value = data;
  // nodeDetailVisible.value = true;
}

// 获取有效的边对象
function getValidEdge(event: any, edge: Edge): Edge | null {
  // 如果第一个参数是edge对象
  if (edge && edge.id && edge.source && edge.target) {
    return edge;
  }
  // 如果第一个参数是事件对象，第二个参数是edge
  if (event && event.id && event.source && event.target) {
    return event;
  }
  // 尝试从Vue Flow实例获取
  const currentEdges = getEdges.value;
  return currentEdges.length > 0 ? currentEdges[0] : null;
}

// 边右键菜单事件
function onEdgeContextMenu(event: any) {
  const edge = event as Edge;
  if (event && typeof event.preventDefault === 'function') {
    event.preventDefault();
  }

  const targetEdge = getValidEdge(event, edge);
  if (!targetEdge || !targetEdge.data || !targetEdge.id) {
    console.error('无效的边对象');
    return;
  }

  const tenantName = targetEdge.data?.tenant?.tenantName || '未知租户';
  const nodeInfo = targetEdge.data?.node ? `${targetEdge.data.node.ip}:${targetEdge.data.node.port}` : '未知节点';

  Modal.confirm({
    title: '确认删除',
    content: `确定要删除租户 "${tenantName}" 到节点 "${nodeInfo}" 的映射关系吗？`,
    okText: '确定',
    cancelText: '取消',
    onOk: () => {
      deleteEdge(targetEdge.id);
    }
  });
}

// 通用删除映射函数
async function deleteMapping(mappingId: string | null, edgeId: string | null = null, closeModal = false) {
  // 如果有映射ID，调用后端接口删除
  if (mappingId) {
    // 将string类型的mappingId转换为number类型
    const id = Number(mappingId);
    if (Number.isNaN(id)) {
      window.$message?.error('无效的映射ID');
      return;
    }
    const deleteRes = await fetchDeleteTenantNodeMapping(id);
    if (deleteRes.error) {
      return;
    }
  }

  // 如果有边ID，从画布中移除边
  if (edgeId) {
    removeEdges([edgeId]);
  }

  if (closeModal) {
    showMappingModal.value = false;
  }

  window.$message?.success('删除映射成功');

  // 重新加载数据
  await initData();
}

// 删除选中的映射
async function deleteSelectedMapping() {
  if (!selectedMapping.value) return;

  let mappingId = null;
  let edgeId = null;

  if (selectedMapping.value.mapping && selectedMapping.value.mapping.id) {
    mappingId = selectedMapping.value.mapping.id;
    edgeId = `edge-${mappingId}`;
  } else {
    // 查找对应的边ID
    const edgeToRemove = edges.value.find(
      edge =>
        edge.data?.tenant?.id === selectedMapping.value.tenant?.id &&
        edge.data?.node?.ip === selectedMapping.value.node?.ip &&
        edge.data?.node?.port === selectedMapping.value.node?.port
    );
    if (edgeToRemove) {
      edgeId = edgeToRemove.id;
    }
  }

  await deleteMapping(mappingId, edgeId, true);
}

// 删除指定的边
async function deleteEdge(edgeId: string) {
  const edge = edges.value.find(e => e.id === edgeId);
  if (!edge) return;

  let mappingId = null;
  if (edge.data?.mapping && edge.data.mapping.id) {
    mappingId = edge.data.mapping.id;
  }

  await deleteMapping(mappingId, edgeId);
}

// 保存所有映射
async function saveAllMappings() {
  saving.value = true;
  try {
    // 获取所有新的映射关系
    const newMappings = edges.value
      .filter(edge => edge.data?.isNew)
      .map(edge => ({
        tenantId: edge.data.tenant.id,
        nodeIp: edge.data.node.ip,
        nodePort: Number.parseInt(edge.data.node.port, 10),
        status: '1' as Api.Common.EnableStatus
      }));

    if (newMappings.length === 0) {
      window.$message?.warning('没有新的映射关系需要保存');
      return;
    }

    const saveRes = await fetchBatchCreateTenantNodeMappings(newMappings);
    if (saveRes.error) {
      return;
    }

    window.$message?.success('保存映射成功');

    // 更新已保存的映射状态，而不是重新加载所有数据
    const savedMappings = await fetchGetAllTenantNodeMappings();
    if (savedMappings.error) {
      return;
    }
    mappingList.value = savedMappings.data || [];

    // 重新构建流程图元素
    buildFlowElements();
  } finally {
    saving.value = false;
  }
}

// 清空所有映射
function clearAllMappings() {
  removeEdges(edges.value.map(edge => edge.id));
  window.$message?.success('已清空所有映射关系');
}

// 添加映射
async function addMapping() {
  if (!newMapping.value.tenantId || !newMapping.value.nodeKey) {
    window.$message?.warning('请选择租户和节点');
    return;
  }

  addingMapping.value = true;
  try {
    // 解析节点信息
    const [nodeIp, nodePort] = newMapping.value.nodeKey.split('-');

    // 检查租户状态
    const selectedTenant = tenantList.value.find(t => t.id === newMapping.value.tenantId);
    if (!selectedTenant) {
      window.$message?.error('租户信息不存在');
      return;
    }

    if (selectedTenant.status !== '1') {
      window.$message?.warning('禁用状态的租户不能添加映射关系');
      return;
    }

    // 检查是否已存在相同的映射
    const existingEdge = edges.value.find(edge => {
      const tenant = edge.data?.tenant;
      const node = edge.data?.node;
      return tenant?.id === newMapping.value.tenantId && node?.ip === nodeIp && node?.port === nodePort;
    });

    if (existingEdge) {
      window.$message?.warning('该映射关系已存在');
      return;
    }

    // 调用后端接口创建映射
    const mappingData = {
      tenantId: newMapping.value.tenantId,
      nodeIp,
      nodePort: Number.parseInt(nodePort, 10),
      status: newMapping.value.status
    };

    const createRes = await fetchCreateTenantNodeMapping(mappingData);
    if (createRes.error) {
      return;
    }

    // 重新加载映射数据
    const savedMappings = await fetchGetAllTenantNodeMappings();
    if (savedMappings.error) {
      return;
    }
    mappingList.value = savedMappings.data || [];

    // 重新构建流程图元素
    buildFlowElements();

    // 重置表单
    newMapping.value = {
      tenantId: null,
      nodeKey: null,
      status: '1'
    };

    showAddMappingModal.value = false;
    window.$message?.success('添加映射成功');
  } finally {
    addingMapping.value = false;
  }
}

// 监听数据变化
watch(
  [tenantList, nodeList, mappingList],
  () => {
    buildFlowElements();
  },
  { deep: true }
);

// 初始化
onMounted(() => {
  initData();
});

// 添加组件卸载钩子
onUnmounted(() => {
  // 确保Vue Flow实例被正确销毁
  if (vueFlowRef.value) {
    vueFlowRef.value.destroy();
  }
  // 清理可能的事件监听器或其他资源
  console.log('Vue Flow组件资源已清理');
});
</script>

<template>
  <div class="vue-flow-container">
    <div class="toolbar">
      <div class="toolbar-left">
        <AButton type="primary" @click="initData">
          <template #icon>
            <icon-ic-round-refresh class="text-16px" />
          </template>
          刷新数据
        </AButton>
        <AButton :loading="saving" :disabled="!hasChanges" @click="saveAllMappings">
          <template #icon>
            <icon-ic-round-save class="text-16px" />
          </template>
          保存映射
        </AButton>
        <AButton :disabled="!hasChanges" @click="clearAllMappings">
          <template #icon>
            <icon-ic-round-clear class="text-16px" />
          </template>
          清空映射
        </AButton>
        <AButton type="primary" @click="showAddMappingModal = true">
          <template #icon>
            <icon-ic-round-add class="text-16px" />
          </template>
          添加映射
        </AButton>
      </div>
      <div class="toolbar-right">
        <ATag color="blue">租户: {{ tenantList.length }}</ATag>
        <ATag color="green">节点: {{ nodeList.length }}</ATag>
        <ATag color="geekblue">映射: {{ edges.length }}</ATag>
      </div>
    </div>

    <div class="flow-container">
      <VueFlow
        ref="vueFlowRef"
        v-model="elements"
        :default-viewport="{ zoom: 0.8 }"
        :min-zoom="0.2"
        :max-zoom="1.5"
        :node-types="nodeTypes"
        :edge-types="edgeTypes"
        :connection-line-style="{ stroke: '#1890ff', strokeWidth: 2 }"
        :connection-mode="ConnectionMode.Loose"
        class="vue-flow"
        @connect="onConnect"
        @edge-click="onEdgeClick"
        @node-click="onNodeClick"
        @edge-context-menu="onEdgeContextMenu"
        @node-drag-stop="onNodeDragStop"
      >
        <Background pattern-color="#aaa" :gap="[8, 8]" />
        <MiniMap />
        <Controls />

        <template #node-tenant="nodeProps">
          <TenantNode :data="nodeProps.data" />
        </template>

        <template #node-node="nodeProps">
          <NodeNode :data="nodeProps.data" @dblclick="showNodeDetail" />
        </template>
      </VueFlow>
    </div>

    <!-- 映射详情弹窗 -->
    <AModal v-model:open="showMappingModal" title="映射详情" :width="500" :footer="null">
      <div v-if="selectedMapping" class="mapping-details">
        <div class="mapping-item">
          <div class="mapping-label">租户:</div>
          <div class="mapping-value">{{ selectedMapping.tenant?.tenantName }}</div>
        </div>
        <div class="mapping-item">
          <div class="mapping-label">节点:</div>
          <div class="mapping-value">{{ selectedMapping.node?.ip }}:{{ selectedMapping.node?.port }}</div>
        </div>
        <div class="mapping-item">
          <div class="mapping-label">状态:</div>
          <div class="mapping-value">
            <ATag :color="selectedMapping.status === '1' ? 'green' : 'orange'">
              {{ selectedMapping.status === '1' ? '启用' : '禁用' }}
            </ATag>
          </div>
        </div>
      </div>
      <template #footer>
        <div class="flex justify-end gap-8px">
          <AButton type="primary" danger @click="deleteSelectedMapping">删除映射</AButton>
          <AButton @click="showMappingModal = false">关闭</AButton>
        </div>
      </template>
    </AModal>

    <!-- 添加映射弹窗 -->
    <AModal v-model:open="showAddMappingModal" title="添加映射" :width="600" @ok="addMapping">
      <div class="add-mapping-form">
        <div class="form-item">
          <label class="form-label">选择租户:</label>
          <ASelect v-model:value="newMapping.tenantId as any" style="width: 100%" :options="tenantOptions" />
        </div>
        <div class="form-item">
          <label class="form-label">选择节点:</label>
          <ASelect
            v-model:value="newMapping.nodeKey as any"
            placeholder="请选择节点"
            style="width: 100%"
            :options="nodeOptions"
          />
        </div>
        <div class="form-item">
          <label class="form-label">状态:</label>
          <ASelect
            v-model:value="newMapping.status"
            placeholder="请选择状态"
            style="width: 100%"
            :options="[
              { label: '启用', value: '1' },
              { label: '禁用', value: '0' }
            ]"
          />
        </div>
      </div>
      <template #footer>
        <div class="flex justify-end gap-8px">
          <AButton @click="showAddMappingModal = false">取消</AButton>
          <AButton type="primary" :loading="addingMapping" @click="addMapping">确定</AButton>
        </div>
      </template>
    </AModal>
  </div>
</template>

<style scoped>
.vue-flow-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: var(--ant-card-bg);
  border-bottom: 1px solid var(--ant-border-color-split);
  gap: 16px;
}

.toolbar-left {
  display: flex;
  gap: 8px;
}

.toolbar-right {
  display: flex;
  gap: 8px;
}

.flow-container {
  flex: 1;
  position: relative;
  height: 100%; /* 确保有明确高度 */
  min-height: 0;
}

.vue-flow {
  background: var(--ant-fill-tertiary);
  height: 100% !important; /* 使用!important确保高度应用 */
  width: 100% !important;
}

.mapping-details {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.mapping-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mapping-label {
  font-weight: 600;
  color: var(--ant-text-color);
  min-width: 60px;
}

.mapping-value {
  color: var(--ant-text-color-secondary);
}

.add-mapping-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.form-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-label {
  font-weight: 600;
  color: var(--ant-text-color);
}

:deep(.vue-flow__node) {
  cursor: pointer;
}

:deep(.vue-flow__edge) {
  cursor: pointer;
}

:deep(.vue-flow__edge:hover) {
  stroke-width: 3;
}

:deep(.vue-flow__controls) {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

:deep(.vue-flow__minimap) {
  border-radius: 8px;
  overflow: hidden;
}
</style>
